#pragma once

#include <iostream>
#include <string>
#include <strings.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <cstring>
#include <stdio.h>
using std::cout;
using std::cerr;
using std::endl;
using std::string;

class TcpClient
{
private:
    string desc_ip;//要访问的目标端ip
    uint16_t desc_port;//要访问的目标端port
    int sock;//打开的网络文件
public:
    TcpClient(string ip,uint16_t port)
        :desc_ip(ip),desc_port(port),sock(-1)
    {
        //进行初始化工作
        //1.创建socket套接字文件
        sock=socket(AF_INET,SOCK_STREAM,0);//ipv4协议，socket类型，传输协议编号
        if(sock < 0)
        {
            cerr<<"sock"<<endl;
            exit(1);
        }
    }
    void start()
    {
        //2.创建socketaddr_in结构体并填入服务端的信息
        struct sockaddr_in desc;
        bzero(&desc,sizeof(desc));
        desc.sin_family=AF_INET;//传输协议
        desc.sin_port=htons(desc_port);//端口号
        desc.sin_addr.s_addr=inet_addr(desc_ip.c_str());//IP地址-点分十进制转四字节ip同时转成网络传输格式

        //对于客户端并不用进行绑定自己的端口-发送数据时会自动进行绑定
        //客户端也不用进行listen-客户端是发起链接的一方，服务端是接收链接的需要保证listen状态

        //tcp是面向链接的
        //3.建立链接关系
        if(connect(sock,(struct sockaddr*)&desc,sizeof(desc)) < 0)
        {
            cerr<<"connect"<<endl;
        }

        //4.执行逻辑
        while(true)
        {
            char buffer[1024]={0};
            cout<<"Please Enter#";//提示符
            fflush(stdout);
            ssize_t s=read(0,buffer,sizeof(buffer)-1);
            if(s>0)
            {
                buffer[s-1]=0;//覆盖回车键
                //向服务端传数据-tcp是流式套接字
                write(sock,buffer,strlen(buffer));
                //接收服务端发来的数据
                ssize_t size=read(sock,buffer,sizeof(buffer)-1);
                if(size>0)
                {
                    buffer[size]=0;
                    cout<<buffer<<endl;
                }
                else
                {
                    cerr<<"server close"<<endl;
                    break;
                }
            }
        }
    }
    ~TcpClient()
    {
        if(sock >= 0)
        close(sock);
    }
};
